﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.Objects.SqlClient;
using thailandProject.Models;
using thailandProject.ViewModel;
using MvcFilters.Infrastructure.Filters;

namespace thailandProject.Controllers
{
    [ThailandAuthorize(2, null, new int[] { -1 })]
    public class EmailController : Controller
    {
        public string To { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }
        //
        // GET: /Email/

        public ActionResult Index()
        {
            try
            {
                ViewBag.Header = "Email";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            // // need list of emails in Richard's gmail inbox (??)
            return View(/*emails*/);
        }

        public ActionResult GenerateEmail()
        {
            try
            {
                ViewBag.Header = "View Generated Email";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View();
        }

        [HttpGet] 
        public ActionResult ViewEmail(int id)
        {
            try
            {
                ViewBag.Header = "Details";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            // need one email based on an id (??)
            return View(/*email*/);
        }

        public ActionResult Compose()
        {
            try
            {
                if (Session["emailMessage"] == null)
                    Session.Add("emailMessage", "");

                ViewBag.Header = "Compose Email";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            return View();
        }

        [HttpPost]
        public ActionResult Compose(FormCollection collection)
        {
            int clientId = -1;
            try
            {
                ViewBag.Header = "Compose Email";

                ThailandEntities a = new ThailandEntities();
                //Find the associated client or create a new one
                clientId = Convert.ToInt32(collection["clientID"]);
                CLIENT client;

                if (clientId == -1)
                {
                    string firstName = collection["clientFirstName"].ToString();
                    string lastName = firstName.IndexOf(" ") != -1 ? firstName.Substring(firstName.IndexOf(" ") + 1,
                        firstName.Substring(firstName.IndexOf(" ") + 1).Length) : null;
                    firstName = firstName.IndexOf(" ") != -1 ? firstName.Substring(0, firstName.IndexOf(" ")) : firstName;

                    //It will be -1 if an existing client was not found
                    client = new CLIENT();
                    client.clientFirstName = firstName;
                    client.clientLastName = lastName;
                    client.clientEmail = collection["to"].ToString();
                    client.clientIsActive = true;
                    a.CLIENTs.AddObject(client);

                    a.SaveChanges(); //Commit the new client
                }
                else
                {
                    //Fetch the pre-existing client
                    var clients = from c in a.CLIENTs
                                  where c.clientID == clientId
                                  select c;

                    client = clients.ToList()[0];
                    client.clientIsActive = true; //Reactivate this client if it already isn't
                }//End to else

                //Create the reservation only if there were properties selected
                USER user = (USER)Session["user"];
                List<PropertyMatch> properties = (List<PropertyMatch>)HttpContext.Application["properties" + user.userID];
                HttpContext.Application.Remove("properties" + user.userID);

                if (properties != null) //Will be null if no properties were passed
                {
                    //Create the reservation
                    List<RESERVATION> newRes = new List<RESERVATION>();

                    //For each apartment intended to be reserved, create a RESERVATION object
                    foreach (PropertyMatch prop in properties)
                    {
                        RESERVATION r = new RESERVATION();
                        r.resDate = DateTime.Now;
                        r.resStartDate = prop.startDate;
                        r.resEndDate = prop.endDate;
                        r.resQuotedPrice = prop.quotedPrice;
                        r.propID = prop.property.propID;
                        r.clientID = client.clientID;
                        r.resDate = DateTime.Now;
                        r.resIsHeld = true; //By default, every reservation is on hold
                        r.userID = ((USER)Session["user"]).userID;

                        newRes.Add(r);
                    }

                    foreach (RESERVATION r in newRes)
                    {
                        a.RESERVATIONs.AddObject(r);
                    }

                    a.SaveChanges(); //Commit all the added objects to the database

                }//End to if property count > 0
                clientId = client.clientID;

                #region Send Email
                //Fetch the current user's email preferences, if they exist
                EMAILPREFERENCE p = getPreferences(1); //(user.userID);
                if (p != null && p.onPropInquiry && collection["donotsend"] == "false") //Will short-circut, hopefully
                {                   
                    //I've disabled this for the moment so it doesn't send emails to random people while we're testing
                    GMailer.SendMail(collection.Get("subject"), collection.Get("to"), collection.Get("body"));
                    //Add the sent email to the database
                    EMAILSENT es = new EMAILSENT();
                    es.clientID = clientId;
                    es.emailContent = htmlConverter.ConvertForDB(collection.Get("body"));
                    es.emailDateSent = DateTime.Now;
                    es.emailSubject = collection.Get("subject");

                    a.EMAILSENTs.AddObject(es);
                    int change = a.SaveChanges();
                }
                #endregion
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return RedirectToAction("ViewClient", "Clients", new { clientId = clientId});
        }

        public ActionResult EmailQuickSearch(string email)
        {
            JsonResult result = new JsonResult();
            try
            {
                ThailandEntities c = new ThailandEntities();

                var clients = c.CLIENTs
                                .Where(r => (r.clientEmail == email))
                                .Take(1)
                                .Select(r => (SqlFunctions.StringConvert((double)r.clientID) + "-" + r.clientFirstName + (r.clientLastName == null ? "" : " " + r.clientLastName)));

                List<string> names = clients.ToList();
                string name;

                if (names.Count > 0)
                    name = names[0];
                else
                    name = null;
                result = Json(name, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return result;
        }

        [HttpGet]
        public ActionResult EventCompose()
        {
            Pair<List<EventEmail>, string> emails = new Pair<List<EventEmail>, string>(new List<EventEmail>(),
                Session["EventEmailReturnURL"].ToString());
            try
            {
                ViewBag.Header = "Email Composer";
                
                List<int> clientIDs = (List<int>) Session["EventEmailClientIDs"];
                Object emailData = Session["EventEmailData"];
                string emailType = Session["EventEmailType"].ToString();

                //Fetch the email preferences
                int userID = 1; // ((USER)Session["user"]).userID;

                //Fetch all of the client's information
                ThailandEntities a = new ThailandEntities();

                var selClients = from client in a.CLIENTs
                              where clientIDs.Contains(client.clientID)
                              select client;
                List<CLIENT> clients = selClients.ToList();

                EMAILPREFERENCE pref = null;
                var prefs = from p in a.EMAILPREFERENCEs
                            where p.userID == userID
                            select p;
                if(prefs.Count() > 0)
                    pref = prefs.ToList()[0];

                foreach (CLIENT c in clients)
                {
                    string message = "";
                    string subject = "";
                    string clientName = String.IsNullOrEmpty(c.clientLastName) ? c.clientFirstName : c.clientFirstName + " " + c.clientLastName;

                    //TODO: Add casting code
                    switch (emailType)
                    {
                        case "onDepositMade":
                            PAYMENT deposit = (PAYMENT)emailData;
                            if (pref != null && !String.IsNullOrEmpty(pref.onDepositMadeTemplate))
                            {
                                string template = pref.onDepositMadeTemplate;
                                message = EmailGenerator.generateOnDepositMade(new EmailTemplateModel(emailType, template), clientName, deposit);
                            }
                            else
                                message = EmailGenerator.onDepositMade(clientName, deposit);
                            subject = "Chiang Mai Apartment Rentals -- Deposit Received";
                            break;
                        case "onRefundMade": 
                            PAYMENT refund = (PAYMENT)emailData;
                            if (pref != null && !String.IsNullOrEmpty(pref.onRefundMadeTemplate))
                            {
                                string template = pref.onRefundMadeTemplate;
                                message = EmailGenerator.generateOnRefundMade(new EmailTemplateModel(emailType, template), clientName, refund);
                            }
                            else
                                message = EmailGenerator.onRefundMade(refund, clientName);
                            subject = "Chiang Mai Apartment Rentals -- Refunded Payment";
                            break;
                        case "onReservationDrop":
                            List<RESERVATION> olRes = ((List<RESERVATION>)emailData).Where(id => id.clientID == c.clientID).ToList();
                            //The olRes does not have any properties attached to it, so get the properties
                            foreach (RESERVATION r in olRes)
                            {
                                var props = from prop in a.PROPERTies
                                            where prop.propID == r.propID
                                            select prop;
                                r.PROPERTY = props.ToList()[0];
                            }
                            if (pref != null && !String.IsNullOrEmpty(pref.onReservationDropTemplate))
                            {
                                string template = pref.onReservationDropTemplate;
                                message = EmailGenerator.generateOnReservationDrop(new EmailTemplateModel(emailType, template), clientName, olRes);
                            }
                            else
                                message = EmailGenerator.onReservationDrop(olRes, clientName);
                            subject = "Chiang Mai Apartment Rentals -- Reservation Cancellation";
                            break;
                        case "onReservationEdit":
                            List<RESERVATION> res = (List<RESERVATION>)emailData;
                            if (pref != null && !String.IsNullOrEmpty(pref.onReservationEditTemplate))
                            {
                                string template = pref.onReservationEditTemplate;
                                message = EmailGenerator.generateOnReservationEdit(new EmailTemplateModel(emailType, template), clientName, res.First(), res.Last());
                            }
                            else
                                message = EmailGenerator.onReservationEdit(res.First(), res.Last(), clientName);
                            subject = "Chiang Mai Apartment Rentals -- Reservation Change";
                            break;
                        default: message = EmailGenerator.generateDummyText(); break;
                    }

                    emails.value1.Add(new EventEmail(subject, message, c));
                }//End to foreach client
                
            }//End to try
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(emails);
        }

        [HttpPost]
        public ActionResult EventCompose(FormCollection data)
        {
            string redirectURL = "";
            try
            {
                redirectURL = data["returnURL"].ToString();
                string[] tos = data["to"].Split(',');
                string[] subjects = data["subject"].Split(',');
                string[] clientIDs = data["clientID"].Split(',');
                string[] messages = new string[tos.Length];

                for (int i = 0; i < messages.Length; i++)
                {
                        messages[i] = data["body_" + i] != null ? data["body_" + i].ToString() : "";
                }

                //Send the emails, now
                if (data["donotsend"] == "false")
                {
                    ThailandEntities a = new ThailandEntities();
                    for (int i = 0; i < tos.Length; i++)
                    {
                        GMailer.SendMail(subjects[i], tos[i], messages[i]);
                        //Log it in the DB
                        EMAILSENT es = new EMAILSENT();
                        es.clientID = Convert.ToInt32(clientIDs[i]);
                        es.emailContent = htmlConverter.ConvertForDB(messages[i]);
                        es.emailDateSent = DateTime.Now;
                        es.emailSubject = subjects[i];

                        a.EMAILSENTs.AddObject(es);
                    }
                    int change = a.SaveChanges();
                }
                
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            if (redirectURL == "")
                return RedirectToAction("Index", "Home");
            else
                return Redirect(redirectURL);
        }

        public static void setEventComposeSession(HttpSessionStateBase Session, string EventEmailReturnURL, List<int> EventEmailClientIDs,
            Object EventEmailData, string EventEmailType)
        {
            if (Session["EventEmailReturnURL"] == null)
                Session.Add("EventEmailReturnURL", EventEmailReturnURL);
            else
                Session["EventEmailReturnURL"] = EventEmailReturnURL;

            if (Session["EventEmailClientIDs"] == null)
                Session.Add("EventEmailClientIDs", EventEmailClientIDs);
            else
                Session["EventEmailClientIDs"] = EventEmailClientIDs;

            if (Session["EventEmailData"] == null)
                Session.Add("EventEmailData", EventEmailData);
            else
                Session["EventEmailData"] = EventEmailData;

            if (Session["EventEmailType"] == null)
                Session.Add("EventEmailType", EventEmailType);
            else
                Session["EventEmailType"] = EventEmailType;
        }

        public static EMAILPREFERENCE getPreferences(int userID)
        {
            EMAILPREFERENCE pref = null;
            ThailandEntities a = new ThailandEntities();

            var prefs = from p in a.EMAILPREFERENCEs
                        where p.userID == userID
                        select p;

            if(prefs.Count() > 0)
                pref = prefs.ToList()[0];

            return pref;
        }
    }
}
